package com.realdtech.wechat.task.sms;

import com.alibaba.fastjson.JSONObject;
import com.jfinal.core.Controller;
import com.jfinal.ext2.kit.RandomKit;
import com.jfinal.kit.HashKit;
import com.jfinal.kit.LogKit;
import com.jfinal.kit.Prop;
import com.jfinal.kit.PropKit;
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpClientParams;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.commons.lang3.time.DateUtils;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLDecoder;
import java.text.MessageFormat;
import java.text.ParseException;
import java.util.Date;

public class SMSSender {

	public static final Account ACCOUNT;

	public static String sendCaptcha(String mobileNos) {

		String content = "尊敬的用户，认证手机验证码：{0}，5分钟内输入有效。金融链工作人员不会索取，请勿泄漏。有问题请致电客服400-606-9989";
		String captcha = RandomKit.smsAuthCode(6);
		content = MessageFormat.format(content, captcha);
		batchSend(mobileNos, content);
		return captcha;
	}

	/**
	 * 短信验证码Cookie名称
	 */
	public static final String CAPTCHA_NAME = "_SMS_CAPTCHA";
	/**
	 * 最后发送时间Cookie名称
	 */
	public static final String CAPTCHA_LAST_SEND_TIME_NAME = "_SMS_CAPTCHA_LAST_SEND_TIME";
	static {

		Prop prop = PropKit.use("sms_253.properties");
		ACCOUNT = new Account(prop.get("url"), prop.get("username"), prop.get("password"));

		if (LogKit.isInfoEnabled()) {
			LogKit.info("短信接口初始化...");
			LogKit.info("短信接口账户信息：" + JSONObject.toJSONString(ACCOUNT));
		}
	}

	/**
	 * 验证短信验证码是否正确
	 * 
	 * @param controller
	 * @param userInputCaptcha
	 * @return
	 */
	public static boolean validateCaptcha(Controller controller, String userInputCaptcha) {

		String captcha1 = controller.getCookie(CAPTCHA_NAME);
		captcha1 = HashKit.md5(captcha1);
		String captcha2 = userInputCaptcha;
		captcha2 = HashKit.md5(captcha2);
		return StringUtils.equalsIgnoreCase(captcha1, captcha2);
	}

	public static SendResult batchSend(String mobile, String msg) {

		return batchSend(mobile, msg, null);
	}

	public static SendResult batchSend(String mobile, String msg, String extno) {

		return batchSend(mobile, msg, true, extno);
	}

	public static SendResult batchSend(String mobile, String msg, boolean needstatus, String extno) {

		String url = SMSSender.ACCOUNT.getUrl();// 应用地址
		String account = SMSSender.ACCOUNT.getUsername();// 账号
		String pwd = SMSSender.ACCOUNT.getPassword();// 密码
		return batchSend(url, account, pwd, mobile, msg, needstatus, extno);
	}

	/**
	 * 
	 * @param url
	 *            应用地址，类似于http://ip:port/msg/
	 * @param account
	 *            账号
	 * @param pwd
	 *            密码
	 * @param mobile
	 *            手机号码，多个号码使用","分割
	 * @param msg
	 *            短信内容
	 * @param needstatus
	 *            是否需要状态报告，需要true，不需要false
	 * @return 返回值定义参见HTTP协议文档
	 */
	public static SendResult batchSend(String url, String account, String pwd, String mobile, String msg,
			boolean needstatus, String extno) {

		HttpClient client = new HttpClient(new HttpClientParams(), new SimpleHttpConnectionManager(true));
		GetMethod method = new GetMethod();
		try {
			URI base = new URI(url, false);
			method.setURI(new URI(base, "HttpBatchSendSM", false));
			method.setQueryString(new NameValuePair[] { new NameValuePair("account", account),
					new NameValuePair("pswd", pwd), new NameValuePair("mobile", mobile),
					new NameValuePair("needstatus", String.valueOf(needstatus)), new NameValuePair("msg", msg),
					new NameValuePair("extno", extno), });
			int result = client.executeMethod(method);
			if (result == HttpStatus.SC_OK) {
				InputStream in = method.getResponseBodyAsStream();
				ByteArrayOutputStream baos = new ByteArrayOutputStream();
				byte[] buffer = new byte[1024];
				int len = 0;
				while ((len = in.read(buffer)) != -1) {
					baos.write(buffer, 0, len);
				}
				String returnString = URLDecoder.decode(baos.toString(), "UTF-8");
				SendResult rst = new SendResult(returnString);
				return rst;
			} else {
				return new SendResult(new Date(), false, method.getStatusCode(), method.getStatusText());
			}
		} catch (URIException e) {
			return new SendResult(new Date(), false, -1, e.getMessage());
		} catch (NullPointerException e) {
			return new SendResult(new Date(), false, -1, e.getMessage());
		} catch (HttpException e) {
			return new SendResult(new Date(), false, -1, e.getMessage());
		} catch (IOException e) {
			return new SendResult(new Date(), false, -1, e.getMessage());
		} finally {
			method.releaseConnection();
		}
	}

	/**
	 * 发送结果
	 * 
	 * @author 王少杰
	 *
	 */
	public static class SendResult {
		public static final String SEPARATOR = ",";

		/**
		 * 手动构建返回结果
		 * 
		 * @param date
		 *            发送日期
		 * @param success
		 *            发送结果
		 * @param errorCode
		 *            错误代码
		 * @param msg
		 *            错误信息
		 */
		public SendResult(Date date, boolean success, int errorCode, String msg) {
			super();
			this.date = date;
			this.success = success;
			this.errorCode = errorCode;
			this.msg = msg;
		}

		/**
		 * 根据返回结果构造
		 * 
		 * @param returnString
		 *            短信结构返回字符串
		 */
		public SendResult(String returnString) {
			if (StringUtils.isNotEmpty(returnString)) {
				String[] arr = StringUtils.split(returnString, SEPARATOR);
				if (arr != null && arr.length == 2) {
					try {
						Date date = DateUtils.parseDate(arr[0], "yyyyMMddHHmmss");
						int errorCode = NumberUtils.toInt(arr[1].toString());

						this.date = date;
						this.errorCode = errorCode;

						if (errorCode == 0) {
							this.success = true;
							this.msg = "发送成功";
						} else {
							this.success = false;
							switch (errorCode) {
							case 101:
								this.msg = "无此用户";
								break;
							case 102:
								this.msg = "密码错误";
								break;
							case 103:
								this.msg = "提交过快（提交速度超过流速限制）";
								break;
							case 104:
								this.msg = "系统忙（因平台原因，暂时无法处理提交的短信）";
								break;
							case 105:
								this.msg = "敏感短信（短信内容包含敏感词）";
								break;
							case 106:
								this.msg = "消息长度错误（>536或<=0）";
								break;
							case 107:
								this.msg = "包含错误的手机号码";
								break;
							case 108:
								this.msg = "手机号码个数错（群发>50000或<=0；单发>200或<=0）";
								break;
							case 109:
								this.msg = "无发送额度（该用户可用短信数已使用完）";
								break;
							case 110:
								this.msg = "不在发送时间内";
								break;
							case 111:
								this.msg = "超出该账户当月发送额度限制";
								break;
							case 112:
								this.msg = "无此产品，用户没有订购该产品";
								break;
							case 113:
								this.msg = "extno格式错（非数字或长度不对）";
								break;
							case 115:
								this.msg = "自动审核驳回";
								break;
							case 116:
								this.msg = "签名不合法，未带签名";
								break;
							case 117:
								this.msg = "IP地址认证错误，请求的IP地址不是系统登记的IP地址";
								break;
							case 118:
								this.msg = "用户没有相应的发送权限";
								break;
							case 119:
								this.msg = "用户已过期";
								break;
							case 120:
								this.msg = "测试内容不是白名单";
								break;
							}
						}
					} catch (ParseException e) {
						e.printStackTrace();
					}
				}
			}
		}

		/**
		 * 发送时间
		 */
		private Date date;
		/**
		 * 发送结果
		 */
		private boolean success;
		private int errorCode;
		private String msg;

		public Date getDate() {

			return date;
		}

		public void setDate(Date date) {

			this.date = date;
		}

		public boolean isSuccess() {

			return success;
		}

		public void setSuccess(boolean success) {

			this.success = success;
		}

		public int getErrorCode() {

			return errorCode;
		}

		public void setErrorCode(int errorCode) {

			this.errorCode = errorCode;
		}

		public String getMsg() {

			return msg;
		}

		public void setMsg(String msg) {

			this.msg = msg;
		}

	}

	public static class Account {

		public Account(String url, String username, String password) {
			super();
			this.url = url;
			this.username = username;
			this.password = password;
		}

		private String url;
		private String username;
		private String password;

		public String getUrl() {

			return url;
		}

		public void setUrl(String url) {

			this.url = url;
		}

		public String getUsername() {

			return username;
		}

		public void setUsername(String username) {

			this.username = username;
		}

		public String getPassword() {

			return password;
		}

		public void setPassword(String password) {

			this.password = password;
		}

	}

	public static void main(String[] args) {

		SendResult sr = batchSend("18910357740", "测试");
		System.out.println(sr.getMsg());
	}
}